from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMessageBox
from templates.Ui_MainWindow import Ui_MainWindow
from db.DbHelper import DbHelper
import sys
import os
from Searcher import Searcher
import asyncio
from task.AsyncTask import AsyncTask

# 打包时需要
import _mssql
import decimal

print(_mssql.__version__)
print(decimal.__version__)


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    # 国家列表
    countries = []
    # 数据类型列表
    DATA_SOURCE_TUPLE = ("采购商", "供应商")
    data_source_list = []
    # 搜索引擎列表
    SEARCH_ENGINE_TUPLE = ("必应", "谷歌代理")
    SEARCH_ENGINE_HOST_TUPLE = ("http://cn.bing.com", "http://ggg363.firstguo.com")
    # 查询数据的帮助类
    dbHelper = DbHelper(os.getcwd() + '/db')
    # 当前的国家
    country = None
    # 当前的数据源类型
    dataType = None

    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.set_enabled(False)
        self.btn_start.clicked.connect(self.start)
        self.cmb_country.currentIndexChanged.connect(self.country_changed)
        self.btn_clear_progress.clicked.connect(self.clear_progress)
        self.btn_check_connection.clicked.connect(self.check_connection)
        self.cmb_search_engine.addItems(self.SEARCH_ENGINE_TUPLE)

    def show(self):
        super(MainWindow, self).show()
        self.load_countries()

    def load_countries(self):
        """加载国家的数据"""
        task = AsyncTask.create_list(lambda t: self.dbHelper.query_countries(),
                                     self.load_countries_done,
                                     lambda e: self.show_message(str(e)))
        task.signal_progress.connect(self.publish_message)
        task.start()
        task.signal_progress.emit(0, 0, "正在连接数据库...")

    def load_countries_done(self, countries):
        try:
            self.set_enabled(True)
            self.countries = countries
            self.cmb_country.addItems(map(lambda cty: cty["name"], self.countries))
            self.country_changed(0)
            self.show_message("数据库连接成功。")
        except Exception as e:
            print(e)
            self.set_enabled(False)

    def set_enabled(self, enabled):
        self.cmb_country.setEnabled(enabled)
        self.cmb_datasource.setEnabled(enabled)
        self.btn_start.setEnabled(enabled)
        self.btn_clear_progress.setEnabled(enabled)
        self.cmb_search_engine.setEnabled(enabled)

    def country_changed(self, index):
        """国家更换时，判断当前的数据源"""
        self.data_source_list.clear()
        self.cmb_datasource.clear()
        country = self.countries[self.cmb_country.currentIndex()]
        data_format = country["data_format"]
        if data_format in [1, 3]:
            self.data_source_list.append("采购商")
        if data_format in [2, 3]:
            self.data_source_list.append("供应商")
        self.cmb_datasource.addItems(self.data_source_list)

    def start(self):
        """开始抓取"""
        self.set_enabled(False)
        self.country = self.countries[self.cmb_country.currentIndex()]
        self.dataType = self.DATA_SOURCE_TUPLE.index(self.data_source_list[self.cmb_datasource.currentIndex()]) + 1
        task = AsyncTask.create(lambda t: self.start_search(t), lambda e: self.show_message(str(e)))
        task.signal_progress.connect(self.publish_message)
        task.signal_dict.connect(self.single_search_done)
        task.signal.connect(lambda: self.set_enabled(True))
        task.start()

    def start_search(self, task):
        cid = self.country["id"]
        name = self.country["name_en"]
        # 查询当前搜索的进度
        task.signal_progress.emit(0, 0, "正在查询进度...")
        progress = self.dbHelper.query_data_progress(cid, self.dataType)
        # 查询最大记录数
        task.signal_progress.emit(0, 0, "正在查询最大记录数...")
        count = self.dbHelper.query_data_count(cid, name, self.dataType)
        task.signal_progress.emit(progress, count, "获取进度成功。")
        print("count: %d, progress: %d" % (count, progress))
        # 开始搜索任务
        self.load_data(task, count, cid, name, self.dataType, progress)

    def load_data(self, task, count, cid, name, data_type, index):
        """加载数据"""
        result = self.dbHelper.query_data(cid, name, data_type, index)
        rows = result["data_list"]
        row_len = len(rows)
        print("query data count: %d" % row_len)
        if row_len > 0:
            host = self.SEARCH_ENGINE_HOST_TUPLE[self.cmb_search_engine.currentIndex()]
            searcher = Searcher(task, count, host)
            for row in rows:
                searcher.search(row)
            # 继续下一轮的搜索
            self.start_search(task)
        else:
            # 搜索完成
            task.signal.emit()

    def single_search_done(self, result):
        """单次搜索完成"""
        f = open("search_log.txt", "a+")
        f.write(str(result))
        f.write("\n")
        f.close()
        self.dbHelper.update_data(self.country, self.dataType, result)
        self.dbHelper.update_data_progress(self.country["id"], self.dataType, result["id"])

    def publish_message(self, progress, total, message):
        """发布消息"""
        if message:
            self.statusbar.showMessage(message)
        if total > 0:
            self.lbl_progress.setText("已完成：%d/%d" % (progress, total))

    def clear_progress(self):
        """清除进度"""
        ret = QMessageBox.warning(self.centralwidget,
                                  "清除警告",
                                  "是否清除当前表的搜索进度?",
                                  QMessageBox.Yes | QMessageBox.No,
                                  QMessageBox.Yes)
        if ret == QMessageBox.Yes:
            country = self.countries[self.cmb_country.currentIndex()]
            data_type = self.DATA_SOURCE_TUPLE.index(self.data_source_list[self.cmb_datasource.currentIndex()]) + 1
            try:
                self.dbHelper.update_data_progress(country["id"], data_type, 0)
                self.show_message("已重置")
            except Exception as e:
                self.show_message(str(e))

    def check_connection(self):
        """检查网络连接"""
        loop = asyncio.get_event_loop()
        future = asyncio.ensure_future(Searcher().check_network_status())
        future.add_done_callback(self.check_connection_done)
        try:
            loop.run_until_complete(future)
        except Exception as e:
            self.show_message(str(e))

    def check_connection_done(self, future):
        self.btn_check_connection.setEnabled(True)
        status = future.result()
        if status == 200:
            self.show_message("网络连接成功。")
        else:
            self.show_message("网络连接失败，错误码：%s。" % status)

    def show_message(self, msg):
        self.statusbar.showMessage(msg)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
